﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ezCloud.Data;
using Microsoft.AspNet.Identity;
using ezCloud.Api.Models;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using ezCloud.Api.Providers;
using ezCloud.Api.Results;
using System.Web.Http.ModelBinding;
using System.Security.Claims;
using System.Web.Script.Serialization;
using System.Collections.ObjectModel;
using ezCloud.Api.Common;
using System.Data.SqlTypes;


namespace ezCloud.Api.Controllers
{
   
    [RoutePrefix("api/Config")]
    
    public class ConfigController : ezController
    {

        private ApplicationUserManager _userManager;

        public ApplicationUserManager UserManager
        {
            get
            {
                return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }



        public ConfigController()
        {
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Test")]
        
        public async Task<IHttpActionResult> Test(TestViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            return Ok();
        }


        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("AllConfigData")]
        public ConfigData getAllConfigData()
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            
            var currentHotel = context.Hotels.Where(htl => htl.HotelId == currentUser.HotelId).FirstOrDefault();
            var roomList = context.Rooms.Where(room => room.HotelId == currentUser.HotelId).ToList();
            var roomTypes = context.RoomTypes.Where(roomType => roomType.HotelId == currentUser.HotelId).ToList();
            var extraServiceTypes = context.ExtraServiceTypes.Where(esType => esType.HotelId == currentUser.HotelId).ToList();
            var extraServiceCategories = context.ExtraServiceCategories.Where(esCat => esCat.HotelId == currentUser.HotelId).ToList();
            var extraServiceItems = context.ExtraServiceItems.Where(esType => esType.HotelId == currentUser.HotelId).ToList();
            var staffs = context.Staffs.Where(stf => stf.HotelId == currentUser.HotelId).ToList();
            return new ConfigData
            {
                currentHotel = currentHotel,
                rooms = roomList,
                roomTypes = roomTypes,
                extraServiceTypes = extraServiceTypes,
                extraServiceCategories = extraServiceCategories,
                extraServiceItems = extraServiceItems,
                staffs = staffs
            };
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Hotel/GetCurrentHotel")]
        public Hotels getCurrentHotel()
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            
            return context.Hotels.Where(htl => htl.HotelId == currentUser.HotelId).FirstOrDefault();
        }

      

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Hotel/SaveCurrentHotel")]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]

        public async Task<IHttpActionResult> saveCurrentHotel(HotelViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            if (model.ezCloudSubDomain != null)
            {
               
                var subDomainHotel = context.Hotels.Where(htl => htl.EzCloudSubdomain == model.ezCloudSubDomain && htl.HotelId != model.HotelId).FirstOrDefault();

                if (subDomainHotel != null)
                {
                    ModelState.AddModelError("Message", "SUB_DOMAIN_HAS_BEEN_ALREADY_TAKEN");
                    return BadRequest(ModelState);
                }
            }

            var oldCurrentHotel = context.Hotels.Where(htl => htl.HotelId == model.HotelId).FirstOrDefault();
            oldCurrentHotel.HotelName = model.HotelName;
            oldCurrentHotel.HotelAddress = model.HotelAddress;
            oldCurrentHotel.HotelEmail = model.HotelEmail;
            oldCurrentHotel.HotelPhone = model.HotelPhone;
            oldCurrentHotel.EzCloudSubdomain = model.ezCloudSubDomain;
            oldCurrentHotel.HotelDomain = model.HotelDomain;
            oldCurrentHotel.HotelWebsite = model.HotelWebsite;
            oldCurrentHotel.HotelLogoUrl = model.HotelLogoUrl;
            oldCurrentHotel.HotelSizeId = model.HotelSizeId;
            oldCurrentHotel.IsActive = model.isActive;

            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok();
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/GetAllRoomType")]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        public List<RoomTypeData> getAllRoomType()
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            
            //return context.RoomTypes.Where(roomType => roomType.HotelId == currentUser.HotelId).ToList();
            List<RoomTypeData> result = new List<RoomTypeData>();
            var roomTypeList = context.RoomTypes.Where(roomType => roomType.HotelId == currentUser.HotelId).OrderBy(ob => ob.OrderNumber).ToList();
            for (int i = 0; i < roomTypeList.Count(); i++ )
            {
                RoomTypeData roomTypeData = new RoomTypeData();
                List<RoomTypePlan> roomTypePlanList = new List<RoomTypePlan>();
                var roomTypeTemp = roomTypeList[i];
                roomTypeTemp.OrderNumber = roomTypeTemp.OrderNumber == null ? 0 : roomTypeTemp.OrderNumber;
                roomTypeData.roomType = roomTypeTemp;

                
                List<RoomPrices> planListInRoomType = context.RoomPrices.Where(rp => rp.HotelId == roomTypeTemp.HotelId && rp.RoomTypeId == roomTypeTemp.RoomTypeId).ToList();
                for (int j = 0; j < planListInRoomType.Count; j++)
                {
                    RoomTypePlan roomTypePlan = new RoomTypePlan();
                    var planTemp = planListInRoomType[j];
                    roomTypePlan.plan = planTemp;
                    List<RoomPriceAdjustment> planDetail = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == planTemp.HotelId && rpa.RoomPriceId == planTemp.RoomPriceId).ToList();
                    roomTypePlan.planDetail = planDetail;
                    roomTypePlanList.Add(roomTypePlan);
                }
                roomTypeData.roomTypePlanList = roomTypePlanList;

                result.Add(roomTypeData);

            }

            return result;
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/SaveRoomType")]
        public async Task<IHttpActionResult> SaveRoomType(RoomTypeViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            RoomTypes currentRoomType = context.RoomTypes.Where(roomType => roomType.RoomTypeId == model.RoomTypeId).Single();
            currentRoomType.RoomTypeName = model.RoomTypeName;
            currentRoomType.RoomTypeCode = model.RoomTypeCode;
            currentRoomType.RoomTypeDescription = model.RoomTypeDescription;
            currentRoomType.Image = model.Image;
            currentRoomType.Price = model.Price;
            currentRoomType.HotelId = currentClientUser.HotelId;
            currentRoomType.IsHidden = model.IsHidden;
            currentRoomType.DefaultAdults = model.DefaultAdults;
            currentRoomType.DefaultChilds = model.DefaultChilds;
            currentRoomType.OrderNumber = model.OrderNumber == null ? 0 : model.OrderNumber;
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/CreateRoomType")]
        public async Task<IHttpActionResult> CreateRoomType(RoomTypeViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            RoomTypes newRoomTypes = new Data.RoomTypes();
            newRoomTypes.RoomTypeName = model.RoomTypeName;
            newRoomTypes.RoomTypeCode = model.RoomTypeCode;
            newRoomTypes.RoomTypeDescription = model.RoomTypeDescription;
            newRoomTypes.Image = model.Image;
            newRoomTypes.Price = model.Price;
            newRoomTypes.HotelId = currentClientUser.HotelId;
            newRoomTypes.IsHidden = model.IsHidden;
            newRoomTypes.DefaultAdults = model.DefaultAdults;
            newRoomTypes.DefaultChilds = model.DefaultChilds;
            newRoomTypes.OrderNumber = model.OrderNumber == null ? 0 : model.OrderNumber;
            context.RoomTypes.InsertOnSubmit(newRoomTypes);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            RoomPrices defaultRoomPrice = new RoomPrices();
            defaultRoomPrice.HotelId = currentClientUser.HotelId;
            defaultRoomPrice.RoomPriceName = "DEFAULT";
            defaultRoomPrice.FullDayPrice = newRoomTypes.Price;
            defaultRoomPrice.DefaultAdults = newRoomTypes.DefaultAdults;
            defaultRoomPrice.DefaultChildren = newRoomTypes.DefaultChilds;
            defaultRoomPrice.UseFullDayPrice = true;
            defaultRoomPrice.RoomTypeId = newRoomTypes.RoomTypeId;
            defaultRoomPrice.IsActive = true;
            context.RoomPrices.InsertOnSubmit(defaultRoomPrice);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok(newRoomTypes);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/GetAllRoomTypeReservations")]
        public object GetAllRoomTypeReservations(int roomTypeId)
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var currentHotel = context.Hotels.Where(ht => ht.HotelId == currentClientUser.HotelId).FirstOrDefault();
            var timeZoneOffset = -currentHotel.TimeZoneOffset / 60;
            TimeSpan offSet = new TimeSpan(timeZoneOffset, 0, 0);
            var reservationRooms = context.ReservationRooms.Where(rr => rr.HotelId == currentClientUser.HotelId && rr.RoomTypeId == roomTypeId && (rr.BookingStatus == "CHECKIN" || rr.BookingStatus == "BOOKED"))
                .Select(rr => new
                {
                    rr.BookingStatus,
                    rr.Adults,
                    rr.Child,
                    rr.ArrivalDate,
                    rr.DepartureDate,
                    rr.Rooms,
                    rr.Reservations,
                    Travellers = new
                    {
                        rr.Travellers.Fullname
                    },
                    rr.RoomPrices,
                    rr.RoomTypes,
                    rr.RoomId,
                    rr.RoomTypeId,
                    rr.ReservationRoomId,
                    rr.TravellersList,
                    rr.Foc,
                    rr.DiscountPercentage,
                    rr.DiscountFlat,
                    rr.RoomPriceId
                }).ToList();
            return reservationRooms;

        }
        [HttpGet]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/CheckDataRoomTypes")]
        public bool CheckDataRoomTypes(int roomTypeId)
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var currentHotel = context.Hotels.Where(ht => ht.HotelId == currentClientUser.HotelId).FirstOrDefault();
            var timeZoneOffset = -currentHotel.TimeZoneOffset / 60;
            TimeSpan offSet = new TimeSpan(timeZoneOffset, 0, 0);
            var flag = false;
            var reservationRooms = context.ReservationRooms.Where(rr => rr.HotelId == currentClientUser.HotelId && rr.RoomTypeId == roomTypeId && (rr.BookingStatus == "CHECKIN" || rr.BookingStatus == "BOOKED"))
                .Select(rr => new
                {
                    rr.BookingStatus,
                    rr.Adults,
                    rr.Child,
                    rr.ArrivalDate,
                    rr.DepartureDate,
                    rr.Rooms,
                    rr.Reservations,
                    Travellers = new
                    {
                        rr.Travellers.Fullname
                    },
                    rr.RoomPrices,
                    rr.RoomTypes,
                    rr.RoomId,
                    rr.RoomTypeId,
                    rr.ReservationRoomId,
                    rr.TravellersList,
                    rr.Foc,
                    rr.DiscountPercentage,
                    rr.DiscountFlat,
                    rr.RoomPriceId
                }).ToList();
            var rooms = context.Rooms.Where(m => m.HotelId == currentClientUser.HotelId && m.RoomTypeId == roomTypeId && m.IsDeleted == false).ToList();
            if(rooms.Count()>0 || reservationRooms.Count() > 0)
            {
                flag = true;
            }
            //return reservationRooms;
            return flag;

        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/ChangeRoomTypeStatus")]
        public async Task<IHttpActionResult> ChangeRoomTypeStatus(int roomTypeId)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            RoomTypes roomType = context.RoomTypes.Where(rt => rt.HotelId == currentClientUser.HotelId && rt.RoomTypeId == roomTypeId).FirstOrDefault();

            roomType.IsHidden = (roomType.IsHidden == true) ? false : true;

            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok(roomType.IsHidden);

        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/Plans/ChangePlanStatus")]
        public async Task<IHttpActionResult> ChangeRoomTypeStatus(PlanViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            RoomTypes roomType = context.RoomTypes.Where(rt => rt.HotelId == currentClientUser.HotelId && rt.RoomTypeId == model.RoomTypeId).FirstOrDefault();

            RoomPrices plan = context.RoomPrices.Where(rp => rp.RoomTypeId == model.RoomTypeId && rp.RoomPriceId == model.RoomPriceId).FirstOrDefault();

            plan.IsActive = (plan.IsActive == true) ? false : true;

            //roomType.IsHidden = (roomType.IsHidden == true) ? false : true;

            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok(plan.IsActive);

        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/AllRoomType")]
        public async Task<IHttpActionResult> AllRoomType()
        {
            

            var currentClientUser = Common.UserUtitily.getUserProfile();
            var roomTypes = context.RoomTypes.Where(rt => rt.HotelId == currentClientUser.HotelId && !rt.IsHidden).ToList();
            return Ok(roomTypes);
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/GetAllRoom")]
        public async Task<IHttpActionResult> GetAllRoom()
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            
            var rooms = context.Rooms.Where(room => room.HotelId == currentUser.HotelId && room.IsDeleted == false)
                .Select(room => new
                {
                    room,
                    roomTypes = room.RoomTypes,
                    //roomRepairs = room.RoomRepairList.Select(roomRepair => new {
                    //    roomRepair,
                    //    LastModifyDate = roomRepair.ModifyDate,
                    //    LastModifyUser = roomRepair.CreatedByAspNetUsers
                    //}).ToList(),
                    //roomActiveHistories = room.RoomActiveHistoryList
                })
                .ToList();
            //IEnumerable<RoomTypes> roomTypes = context.RoomTypes.Where(types => types.HotelId == currentUser.HotelId).ToList();
            //IEnumerable<RoomRepair> roomRepairs = context.RoomRepair.Where(repair => repair.HotelId == currentUser.HotelId).ToList();
            //IEnumerable<RoomActiveHistory> roomActiveHistories = context.RoomActiveHistory.Where(history => history.HotelId == currentUser.HotelId);
            //return Ok(new 
            //{
            //    rooms = rooms,
            //    roomRepairs = roomRepairs,
            //    roomTypes = roomTypes,
            //    roomActiveHistories = roomActiveHistories
            //});
            return Ok(rooms);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/AllRoomHistory")]
        public async Task<IHttpActionResult> AllRoomHistory(int roomId)
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            var roomActiveHistories = context.RoomActiveHistory.Where(rp => rp.HotelId == currentUser.HotelId && rp.RoomId == roomId).
                Select(roomHistory => new {
                    roomHistory = roomHistory,
                    CreatedUser = context.AspNetUsers.FirstOrDefault(usr => usr.Id == roomHistory.CreatedUserId)
                })
                .ToList();
            return Ok(roomActiveHistories);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/AllRoomRepair")]
        public async Task<IHttpActionResult> AllRoomRepair(int roomId)
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            var roomRepairs = context.RoomRepair.Where(rp => rp.HotelId == currentUser.HotelId && rp.RoomId == roomId).
                Select(roomRepair => new
                {
                    roomRepair,
                    LastModifyDate = roomRepair.ModifyDate,
                    LastModifyUser = context.AspNetUsers.FirstOrDefault(usr => usr.Id == roomRepair.ModifyBy)
                }).ToList();
            return Ok(roomRepairs);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER,ROLE_HOTEL_STAFF")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/EditRoomRepair")]
       
        public async Task<IHttpActionResult> EditRoomRepair(RoomRepair model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var user = Common.UserUtitily.getUserProfile();
            var conflictReservation = context.ReservationRooms.Where(r => r.HotelId == user.HotelId && r.RoomId == model.RoomId && r.BookingStatus != "CANCELLED" && ((r.ArrivalDate < model.RepairEndDate && model.RepairStartDate <= r.DepartureDate))).FirstOrDefault();
            if (conflictReservation != null)
            {
                ObjectExtensions.AddProperty(conflictReservation, "reservationNumber", conflictReservation.Reservations.ReservationNumber);
                return Content(HttpStatusCode.BadRequest, conflictReservation);
            }
            var oldRoomRepair = context.RoomRepair.FirstOrDefault(rm => rm.HotelId == user.HotelId && rm.RoomRepairId == model.RoomRepairId);
            if (oldRoomRepair != null)
            {
                var arrivalDate = oldRoomRepair.RepairStartDate;
                var departureDate = oldRoomRepair.RepairEndDate;
                var roomTypeId = context.Rooms.FirstOrDefault(r => r.HotelId == user.HotelId && r.RoomId == model.RoomId).RoomTypeId;

                oldRoomRepair.RepairStartDate = model.RepairStartDate;
                oldRoomRepair.RepairEndDate = model.RepairEndDate;
                oldRoomRepair.RepairReason = model.RepairReason;
                oldRoomRepair.ModifyDate = DateTime.UtcNow;
                oldRoomRepair.ModifyBy = user.UserId;
                context.SubmitChanges();
                //Elastic.IndexLastAudit(context);

                // Consider only if hotel is using module "Channel Mananger"
                // Room Availabl
                
                var RRTemp = new ReservationRooms();
                RRTemp.ArrivalDate = oldRoomRepair.RepairStartDate;
                RRTemp.DepartureDate = oldRoomRepair.RepairEndDate;
                RRTemp.RoomTypeId = roomTypeId;
                ReservationUtility.RebuildAvailableRoom(RRTemp, user, context,true);

                var RRTemp1 = new ReservationRooms();
                RRTemp1.ArrivalDate = arrivalDate;
                RRTemp1.DepartureDate = departureDate;
                RRTemp1.RoomTypeId = roomTypeId;
                ReservationUtility.RebuildAvailableRoom(RRTemp1, user, context, true);
            }
            return Ok(oldRoomRepair);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER,ROLE_HOTEL_STAFF")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/AddRoomRepair")]
        public async Task<IHttpActionResult> AddRoomRepair(RoomRepair model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var user = Common.UserUtitily.getUserProfile();
            var conflictReservation = context.ReservationRooms.Where(r => r.HotelId == user.HotelId && r.RoomId == model.RoomId && r.BookingStatus!= "CANCELLED" && ((model.RepairStartDate <= r.DepartureDate && r.ArrivalDate <= model.RepairEndDate))).FirstOrDefault();
            if (conflictReservation != null)
            {
                ObjectExtensions.AddProperty(conflictReservation, "reservationNumber", conflictReservation.Reservations.ReservationNumber);
                return Content(HttpStatusCode.BadRequest, conflictReservation);
            }
            var newRoomRepair = new RoomRepair()
            {
                HotelId = user.HotelId,
                RoomId = model.RoomId,
                RepairStartDate = model.RepairStartDate,
                RepairEndDate = model.RepairEndDate,
                RepairReason = model.RepairReason,
                CreatedDate = DateTime.UtcNow,
                CreatedBy = user.UserId,
                ModifyBy = user.UserId,
                ModifyDate = DateTime.UtcNow,
                IsDeleted = false
            };
            context.RoomRepair.InsertOnSubmit(newRoomRepair);
            context.SubmitChanges();
            Elastic.IndexLastAudit(context);

            // Consider only if hotel is using module "Channel Mananger"
            // Room Availabl
            var roomTypeId = context.Rooms.FirstOrDefault(r => r.HotelId == user.HotelId && r.RoomId == model.RoomId).RoomTypeId ;
            var RRTemp = new ReservationRooms();
            RRTemp.ArrivalDate = model.RepairStartDate;
            RRTemp.DepartureDate = model.RepairEndDate;
            RRTemp.RoomTypeId = roomTypeId;
            ReservationUtility.RebuildAvailableRoom(RRTemp, user, context,true);

            return Ok(newRoomRepair);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER,ROLE_HOTEL_STAFF")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/RemoveRoomRepair")]
        public async Task<IHttpActionResult> RemoveRoomRepair(RoomRepair model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var user = Common.UserUtitily.getUserProfile();
            var oldRoomRepair = context.RoomRepair.FirstOrDefault(rp => rp.HotelId == user.HotelId && rp.RoomRepairId == model.RoomRepairId);
            if (oldRoomRepair != null)
            {
                var arrivalDate = oldRoomRepair.RepairStartDate;
                var departureDate = oldRoomRepair.RepairEndDate;
                var roomTypeId = context.Rooms.FirstOrDefault(r => r.HotelId == user.HotelId && r.RoomId == model.RoomId).RoomTypeId;

                if (oldRoomRepair.RepairEndDate.Value.Date < DateTime.UtcNow.Date)
                {
                    return BadRequest("CAN_NOT_UNBLOCK_ROOM_IN_THE_PAST");
                }
                
                if (oldRoomRepair.RepairStartDate <= DateTime.UtcNow && DateTime.UtcNow < oldRoomRepair.RepairEndDate)
                {
                    if (oldRoomRepair.RepairStartDate.Value.Date == oldRoomRepair.RepairEndDate.Value.Date)
                    {
                        oldRoomRepair.IsDeleted = true;
                    }
                    else
                    {
                        oldRoomRepair.RepairEndDate = DateTime.UtcNow;
                        oldRoomRepair.ModifyBy = user.UserId;
                        oldRoomRepair.ModifyDate = DateTime.UtcNow;
                    }
                    
                }
                else
                {
                    oldRoomRepair.IsDeleted = true;
                }
                context.SubmitChanges();
                Common.Elastic.IndexLastAudit(context);

                // Consider only if hotel is using module "Channel Mananger"
                // Room Availabl
                
                var RRTemp = new ReservationRooms();
                RRTemp.ArrivalDate = oldRoomRepair.RepairStartDate;
                RRTemp.DepartureDate = oldRoomRepair.RepairEndDate;
                RRTemp.RoomTypeId = roomTypeId;
                ReservationUtility.RebuildAvailableRoom(RRTemp, user, context,true);


                var RRTemp1 = new ReservationRooms();
                RRTemp1.ArrivalDate = arrivalDate;
                RRTemp1.DepartureDate = departureDate;
                RRTemp1.RoomTypeId = roomTypeId;
                ReservationUtility.RebuildAvailableRoom(RRTemp1, user, context, true);
            }


            return Ok(oldRoomRepair);
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/SaveRoom")]
        public async Task<IHttpActionResult> SaveRoom(RoomViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            

            var currentClientUser = Common.UserUtitily.getUserProfile();

            var oldRR = context.ReservationRooms.Where(rr => rr.HotelId == currentClientUser.HotelId && rr.RoomId == model.RoomId && (rr.BookingStatus == "CHECKIN" || rr.BookingStatus =="BOOKED")).ToList();
            Rooms oldRoom = context.Rooms.Where(room => room.HotelId == currentClientUser.HotelId && room.RoomId == model.RoomId).Single();
            if (oldRR.Count() == 0)
            {   
                if (oldRoom == null)
                {
                    return BadRequest("ROOM_NOT_FOUND");
                }
            }
            else
            {
                var oldRRCheckin = oldRR.Where(r => r.BookingStatus == "CHECKIN").FirstOrDefault();
                // if this room has a guest in house or change room type, the system will be rase error
                if (oldRoom.RoomTypeId != model.RoomTypeId || oldRRCheckin != null)
                    return BadRequest("CAN_NOT_CHANGE_ACTIVE_ROOM");
            }
            if (oldRR!=null)
            {
                oldRoom.RoomName = model.RoomName;
                oldRoom.RoomLocation = model.RoomLocation;
                oldRoom.RoomDescription = model.RoomDescription;
                oldRoom.RoomTypeId = model.RoomTypeId;
                oldRoom.FloorId = model.FloorId == 0 ? null : model.FloorId;
                oldRoom.HotelId = currentClientUser.HotelId;
                oldRoom.IsHidden = model.IsHidden;
                //context.Rooms.InsertOnSubmit(currentRoom);
                context.SubmitChanges();
                Common.Elastic.IndexLastAudit(context);
               
            }
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/CreateRoom")]
        public async Task<IHttpActionResult> CreateRoom(RoomViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            Rooms newRooms = new Data.Rooms();
            newRooms.RoomName = model.RoomName;
            newRooms.RoomLocation = model.RoomLocation;
            newRooms.RoomDescription = model.RoomDescription;
            newRooms.RoomTypeId = model.RoomTypeId;
            newRooms.HotelId = currentClientUser.HotelId;
            //newRooms.HouseStatus = model.HouseStatus;
            newRooms.IsHidden = model.IsHidden;
            newRooms.CreatedDate = DateTime.UtcNow;
            newRooms.CreatedUserId = currentClientUser.UserId;
            newRooms.FloorId = model.FloorId == 0 ? null : model.FloorId;
            newRooms.OrderNumber = 0;
            newRooms.Priority = context.Rooms.Where(rm => rm.HotelId == currentClientUser.HotelId).ToList().Count;

            context.Rooms.InsertOnSubmit(newRooms);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            //ROOM HISTORY
            //var roomList = context.Rooms.Where(rm => rm.HotelId == hotel.HotelId).ToList();

            var roomAH = new RoomActiveHistory
            {
                HotelId = currentClientUser.HotelId,
                RoomId = newRooms.RoomId,
                Date = newRooms.CreatedDate,
                Status = "ACTIVE"
            };
             
            context.RoomActiveHistory.InsertOnSubmit(roomAH);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);



            return Ok(newRooms);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/ChangeRoomStatus")]
        public async Task<IHttpActionResult> ChangeRoomStatus(int roomId)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            var room = context.Rooms.FirstOrDefault(rm => rm.HotelId == currentClientUser.HotelId && rm.RoomId == roomId);

            if (room != null)
            {
                room.IsHidden = (room.IsHidden == true) ? false : true;
                var roomStatus = (room.IsHidden == true) ? "DEACTIVE" : "ACTIVE";
                /*var roomHistory =
                    context.RoomActiveHistory.FirstOrDefault(
                        rm => rm.HotelId == currentClientUser.HotelId && rm.RoomId == roomId && rm.Status == roomStatus && rm.Date == DateTime.UtcNow.Date);
                if (roomHistory != null)
                {
                    
                }*/

                var roomAH = new RoomActiveHistory()
                {
                    HotelId = currentClientUser.HotelId,
                    RoomId = room.RoomId,
                    Date = DateTime.UtcNow,
                    Status = roomStatus,
                    CreatedUserId = currentClientUser.UserId
                };
                context.RoomActiveHistory.InsertOnSubmit(roomAH);
                context.SubmitChanges();
                Common.Elastic.IndexLastAudit(context);
            }
            

            return Ok();

        }

        [HttpGet]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("DeleteRoom")]
        public async Task<IHttpActionResult> DeleteRoom(int roomId)
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var room = context.Rooms.Where(r => r.HotelId == currentClientUser.HotelId && r.RoomId == roomId && r.IsDeleted == false).FirstOrDefault();
            if (room == null)
            {
                return BadRequest("ROOM_IS_NOT_EXISTS");
            }
            //
            var currentHotel = context.Hotels.Where(ht => ht.HotelId == currentClientUser.HotelId).FirstOrDefault();
            var timeZoneOffset = -currentHotel.TimeZoneOffset / 60;
            TimeSpan offSet = new TimeSpan(timeZoneOffset, 0, 0);

            var reservationRooms = context.ReservationRooms
                .Where(rr => rr.HotelId == currentClientUser.HotelId && rr.RoomId == roomId && (rr.BookingStatus == "CHECKIN" || rr.BookingStatus == "BOOKED") )
                .ToList();
            if(reservationRooms.Count() > 0)
            {
                return BadRequest("CAN_NOT_DELETE_THIS_ROOM.PLEASE_PROCESS_ALL_RESERVATION");
            }
            //
            var roomRepair = context.RoomRepair.Where(rr => rr.HotelId == currentClientUser.HotelId && rr.RoomId == room.RoomId && (rr.RepairStartDate >= DateTime.UtcNow || rr.RepairEndDate >= DateTime.UtcNow) && rr.IsDeleted == false ).ToList();
            if(roomRepair.Count() > 0)
            {
                return BadRequest("CAN_NOT_DELETE_THIS_ROOM.PLEASE_PROCESS_ALL_MAINTENANCE_BLOCK");
            }
            room.IsDeleted = true;
            room.IsHidden = true;
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/GetAllRoomReservations")]
        public object GetAllRoomReservations(int roomId)
        {
            
            
            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var currentHotel = context.Hotels.Where(ht => ht.HotelId == currentClientUser.HotelId).FirstOrDefault();
            var timeZoneOffset = -currentHotel.TimeZoneOffset / 60;
            TimeSpan offSet = new TimeSpan(timeZoneOffset, 0, 0);
            var reservationRooms = context.ReservationRooms.Where(rr => rr.HotelId == currentClientUser.HotelId && rr.RoomId == roomId && (rr.BookingStatus=="CHECKIN" || rr.BookingStatus=="BOOKED"))
                .Select(rr => new
                {
                    rr.BookingStatus,
                    rr.Adults,
                    rr.Child,
                    rr.ArrivalDate,
                    rr.DepartureDate,
                    rr.Rooms,
                    rr.Reservations,
                    Travellers = new
                    {
                        rr.Travellers.Fullname
                    },
                    rr.RoomPrices,
                    rr.RoomTypes,
                    rr.RoomId,
                    rr.RoomTypeId,
                    rr.ReservationRoomId,
                    rr.TravellersList,
                    rr.Foc,
                    rr.DiscountPercentage,
                    rr.DiscountFlat,
                    rr.RoomPriceId
                }).ToList();
            return reservationRooms;

        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/GetAllRoomRepair")]
        public async Task<IHttpActionResult> GetAllRoomRepairs(int roomId)
        {
            var user = Common.UserUtitily.getUserProfile();
            var room = context.Rooms.FirstOrDefault(rm => rm.HotelId == user.HotelId);
            var roomRepair = new List<RoomRepair>();
            if (room != null)
            {
                roomRepair =
                    context.RoomRepair.Where(rm => rm.HotelId == user.HotelId && rm.RoomId == room.RoomId).ToList();
            }
            return Ok(roomRepair);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Rooms/RoomRepair")]
        public async Task<IHttpActionResult> RoomRepair(RepairViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var currentClientUser = Common.UserUtitily.getUserProfile();

            var room = context.Rooms.FirstOrDefault(rm => rm.HotelId == currentClientUser.HotelId && rm.RoomId == model.roomId);
            if (room != null)
            {
                if (model.action == "CHANGESTATUS")
                {
                    room.HouseStatus = null;
                    room.RepairStartDate = null;
                    room.RepairEndDate = null;
                    
                }//Set Room Available
                else
                {
                    room.HouseStatus = "REPAIR";
                    room.RepairStartDate = model.repairStartDate;
                    room.RepairEndDate = model.repairEndDate;
                    var roomRepair = new RoomRepair()
                    {
                        HotelId = currentClientUser.HotelId,
                        RoomId = room.RoomId,
                        RepairStartDate = model.repairStartDate,
                        RepairEndDate = model.repairEndDate,

                    };
                }
            }

            
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);


            return Ok(room.HouseStatus);

        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/GetAllExtraServices")]
        public ExtraServiceData GetAllExtraServices()
        {
            
            var currentUser = Common.UserUtitily.getUserProfile();
            var extraServiceTypes = context.ExtraServiceTypes.Where(esType => esType.HotelId == currentUser.HotelId).ToList();
            var extraServiceCategories = context.ExtraServiceCategories.Where(esCat => esCat.HotelId == currentUser.HotelId).ToList();
            var extraServiceItems = context.ExtraServiceItems.Where(esType => esType.HotelId == currentUser.HotelId).ToList();
            return new ExtraServiceData
            {
                extraServiceTypes = extraServiceTypes,
                extraServiceCategories = extraServiceCategories,
                extraServiceItems = extraServiceItems
            };
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("HotelApp/GetAllConfig")]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        public async Task<IHttpActionResult> GetAllConfig()
        {

            List<objectHotelAppConfig> Newlist = new List<objectHotelAppConfig>();

            var context = new ezCloudDataContext();
            var user = Common.UserUtitily.getUserProfile();
            //var HotelApp = new HotelAppCode();
            var HotelApp = context.HotelAppCode.Select(a => new
            {
                a.HotelAppCodeId,
                a.HotelAppCodeName,
                Priority=a.Priority==null?0:a.Priority,
                IsDefault=a.IsDefault==null?false:a.IsDefault,
                a.HotelAppCodeType,
                a.Description
            });
            var HotelConfig = context.HotelAppConfig.Where(h => h.HotelId == user.HotelId).Select(p => new { HotelAppCodeId= p.HotelAppCodeId==null?0:p.HotelAppCodeId }).ToList();

            if (HotelConfig.Count()==0)
            {
                foreach (var t in HotelApp)
                {
                    var ot = new HotelAppCode();
                    ot.HotelAppCodeId = t.HotelAppCodeId;
                    ot.HotelAppCodeName = t.HotelAppCodeName;
                    ot.Priority = t.Priority;
                    ot.IsDefault = t.IsDefault;
                    ot.HotelAppCodeType = t.HotelAppCodeType;
                    ot.Description = t.Description;
                    var oHotelConfig = new objectHotelAppConfig();
                    oHotelConfig.HotelApp = ot;
                    oHotelConfig.IsSelected = 0;
                    Newlist.Add(oHotelConfig);
                }
            }
            else
            {
                foreach (var t in HotelApp)
                {
                    var ot = new HotelAppCode();
                    ot.HotelAppCodeId = t.HotelAppCodeId;
                    ot.HotelAppCodeName = t.HotelAppCodeName;
                    ot.Priority = t.Priority;
                    ot.IsDefault = t.IsDefault;
                    ot.HotelAppCodeType = t.HotelAppCodeType;
                    ot.Description = t.Description;
                    var oHotelConfig = new objectHotelAppConfig();
                    oHotelConfig.HotelApp = ot;
                    foreach (var item in HotelConfig)
                    {
                        if (t.HotelAppCodeId == item.HotelAppCodeId)
                        {  
                            oHotelConfig.IsSelected = 1;
                            break;
                        }
                        else
                        {
                            oHotelConfig.IsSelected = 0;
                        }
                    }
                    Newlist.Add(oHotelConfig);

                }

               
            }

           
            var retval = new
            {
                List = Newlist,
                HotelId = user.HotelId

            };

            return Ok(retval);

        }


        public class HotelConfigModel
        {
            public int HotelAppCodeId { get; set; }
            public bool IsSelected { get; set; }
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("HotelApp/UpdateConfig")]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        public async Task<IHttpActionResult> UpdateConfig(HotelConfigModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var oldHotelAppConfig = context.HotelAppConfig.Where(app => app.HotelId == currentClientUser.HotelId && app.HotelAppCodeId == model.HotelAppCodeId).FirstOrDefault();
            if (model.IsSelected)
            {

                if (oldHotelAppConfig == null)
                {
                    HotelAppConfig hotelAppConfig = new HotelAppConfig();
                    hotelAppConfig.HotelId = currentClientUser.HotelId;
                    hotelAppConfig.HotelAppCodeId = model.HotelAppCodeId;
                    context.HotelAppConfig.InsertOnSubmit(hotelAppConfig);
                    context.SubmitChanges();
                }
            }
            else
            {
                if (oldHotelAppConfig != null)
                {
                    context.HotelAppConfig.DeleteOnSubmit(oldHotelAppConfig);
                    context.SubmitChanges();
                }
            }
            return Ok();
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Categories/ChangeCategoryStatus")]
        public async Task<IHttpActionResult> ChangeCategoryStatus(int categoryId)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            ExtraServiceCategories esCat = context.ExtraServiceCategories.Where(cat => cat.HotelId == currentClientUser.HotelId && cat.ExtraServiceCategoryId == categoryId).FirstOrDefault();
            
            esCat.IsHidden = (esCat.IsHidden == true) ? false : true;

           
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok();

        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Categories/AddCategory")]
        public async Task<IHttpActionResult> AddCategory(ExtraServiceCategoryViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            var extraServiceType = context.ExtraServiceTypes.Where(typ => typ.HotelId == currentClientUser.HotelId && typ.ExtraServiceTypeId == model.ExtraServiceTypeId).FirstOrDefault();
            if (extraServiceType == null)
            {
                return BadRequest("EXTRA_SERVICE_TYPE_NOT_FOUND");
            }
            ExtraServiceCategories newCategory = new Data.ExtraServiceCategories();
            newCategory.ExtraServiceCategoryName = model.ExtraServiceCategoryName;
            newCategory.ExtraServiceCategoryDescription = model.ExtraServiceCategoryDescription;
            newCategory.ExtraServiceTypeId = extraServiceType.ExtraServiceTypeId;
            newCategory.HotelId = currentClientUser.HotelId;
            newCategory.IsHidden = model.IsHidden;
            context.ExtraServiceCategories.InsertOnSubmit(newCategory);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok(newCategory);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Categories/EditCategory")]
        public async Task<IHttpActionResult> EditCategory(ExtraServiceCategoryViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            var extraServiceType = context.ExtraServiceTypes.Where(typ => typ.HotelId == currentClientUser.HotelId && typ.ExtraServiceTypeId == model.ExtraServiceTypeId).FirstOrDefault();
            if (extraServiceType == null)
            {
                return BadRequest("EXTRA_SERVICE_TYPE_NOT_FOUND");
            }

            ExtraServiceCategories oldCategory = context.ExtraServiceCategories.Where(cat => cat.ExtraServiceTypeId == extraServiceType.ExtraServiceTypeId && cat.ExtraServiceCategoryId == model.ExtraServiceCategoryId).FirstOrDefault();
            if (oldCategory == null)
            {
                return BadRequest("Error");
            }

            ExtraServiceCategories newCategory = new Data.ExtraServiceCategories();
            newCategory.ExtraServiceCategoryName = model.ExtraServiceCategoryName;
            newCategory.ExtraServiceCategoryDescription = model.ExtraServiceCategoryDescription;
            newCategory.ExtraServiceTypeId = extraServiceType.ExtraServiceTypeId;
            newCategory.HotelId = currentClientUser.HotelId;
            newCategory.ExtraServiceCategoryId = model.ExtraServiceCategoryId;

            var objDiffer = Utilities.GetDifferentContent(newCategory, oldCategory);

            //ExtraServiceCategories newCategory = new Data.ExtraServiceCategories();
            oldCategory.ExtraServiceCategoryName = model.ExtraServiceCategoryName;
            oldCategory.ExtraServiceCategoryDescription = model.ExtraServiceCategoryDescription;
            oldCategory.ExtraServiceTypeId = extraServiceType.ExtraServiceTypeId;
            oldCategory.HotelId = currentClientUser.HotelId;
            //context.ExtraServiceCategories.InsertOnSubmit(oldCategory);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            Utilities.AddLog("CATEGORY_UPDATE", oldCategory.ExtraServiceCategoryId.ToString(), objDiffer);

            return Ok();
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Categories/RemoveCategory")]
        public async Task<IHttpActionResult> RemoveCategory(ExtraServiceCategoryViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            var extraServiceType = context.ExtraServiceTypes.Where(typ => typ.HotelId == currentClientUser.HotelId && typ.ExtraServiceTypeId == model.ExtraServiceTypeId).FirstOrDefault();
            if (extraServiceType == null)
            {
                return BadRequest("EXTRA_SERVICE_TYPE_NOT_FOUND");
            }

            ExtraServiceCategories categoryDeleted = context.ExtraServiceCategories.Where(cat => cat.ExtraServiceTypeId == extraServiceType.ExtraServiceTypeId && cat.ExtraServiceCategoryId == model.ExtraServiceCategoryId).FirstOrDefault();
            if (categoryDeleted == null)
            {
                return BadRequest("CATEGORY_NOT_FOUND");
            }

            var listItemInCategoryDeleted = context.ExtraServiceItems.Where(itm => itm.ExtraServiceCategoryId == model.ExtraServiceCategoryId).ToList();
            if (listItemInCategoryDeleted != null)
            {
                context.ExtraServiceItems.DeleteAllOnSubmit(listItemInCategoryDeleted);
            }

            context.ExtraServiceCategories.DeleteOnSubmit(categoryDeleted);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Items/AddItem")]
        public async Task<IHttpActionResult> AddItem(ExtraServiceItemsViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            var extraServiceType = context.ExtraServiceTypes.Where(typ => typ.HotelId == currentClientUser.HotelId && typ.ExtraServiceTypeId == model.ExtraServiceTypeId).FirstOrDefault();
            if (extraServiceType == null)
            {
                return BadRequest("Error");
            }

            var extraServiceCategory = context.ExtraServiceCategories.Where(cat => cat.ExtraServiceTypeId == model.ExtraServiceTypeId && cat.ExtraServiceCategoryId == model.ExtraServiceCategoryId).FirstOrDefault();
            if (extraServiceCategory == null)
            {
                return BadRequest("Error");
            }


            ExtraServiceItems newItem = new Data.ExtraServiceItems();
            newItem.ExtraServiceItemName = model.ExtraServiceItemName;
            newItem.ExtraServiceItemDescription = model.ExtraServiceItemDescription;
            newItem.ExtraServiceTypeId = extraServiceType.ExtraServiceTypeId;
            newItem.ExtraServiceCategoryId = extraServiceCategory.ExtraServiceCategoryId;
            newItem.HotelId = currentClientUser.HotelId;
            newItem.IsHidden = model.IsHidden;
            newItem.Unit = model.Unit;
            newItem.Price = model.Price;
            newItem.Priority = model.Priority;
            context.ExtraServiceItems.InsertOnSubmit(newItem);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok(newItem);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Items/EditItem")]
        public async Task<IHttpActionResult> EditItem(ExtraServiceItemsViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            var extraServiceType = context.ExtraServiceTypes.Where(typ => typ.HotelId == currentClientUser.HotelId && typ.ExtraServiceTypeId == model.ExtraServiceTypeId).FirstOrDefault();
            if (extraServiceType == null)
            {
                return BadRequest("Error");
            }

            var extraServiceCategory = context.ExtraServiceCategories.Where(cat => cat.ExtraServiceTypeId == model.ExtraServiceTypeId && cat.ExtraServiceCategoryId == model.ExtraServiceCategoryId).FirstOrDefault();
            if (extraServiceCategory == null)
            {
                return BadRequest("Error");
            }

            ExtraServiceItems oldItem = context.ExtraServiceItems.Where(itm => itm.ExtraServiceTypeId == extraServiceType.ExtraServiceTypeId && itm.ExtraServiceCategoryId == model.ExtraServiceCategoryId && itm.ExtraServiceItemId == model.ExtraServiceItemId).FirstOrDefault();
            if (oldItem == null)
            {
                return BadRequest("Error");
            }


            oldItem.ExtraServiceItemName = model.ExtraServiceItemName;
            oldItem.ExtraServiceItemDescription = model.ExtraServiceItemDescription;
            oldItem.Unit = model.Unit;
            oldItem.Price = model.Price;
            oldItem.ExtraServiceTypeId = extraServiceType.ExtraServiceTypeId;
            oldItem.HotelId = currentClientUser.HotelId;
            oldItem.ExtraServiceCategoryId = extraServiceCategory.ExtraServiceCategoryId;

            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Items/RemoveItem")]
        public async Task<IHttpActionResult> RemoveItem(ExtraServiceItemsViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            ExtraServiceItems itemDeleted = context.ExtraServiceItems.Where(itm => itm.HotelId == currentClientUser.HotelId && itm.ExtraServiceCategoryId == model.ExtraServiceCategoryId && itm.ExtraServiceTypeId == model.ExtraServiceTypeId && itm.ExtraServiceItemId == model.ExtraServiceItemId).FirstOrDefault();
            if (itemDeleted == null)
            {
                return BadRequest("Error");
            }

            context.ExtraServiceItems.DeleteOnSubmit(itemDeleted);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ExtraServices/Items/ChangeItemStatus")]
        public async Task<IHttpActionResult> ChangeItemStatus(int itemId)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            ExtraServiceItems esItem = context.ExtraServiceItems.Where(itm => itm.ExtraServiceItemId == itemId).FirstOrDefault();
            if (esItem.IsHidden == false)
            {
                esItem.IsHidden = true;
            }
            else
            {
                esItem.IsHidden = false;
            }
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok();

        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Staff/GetAllStaffs")]
        public List<ConfigStaffData> getAllStaffs()
        {
            List<ConfigStaffData> result = new List<ConfigStaffData>();
            
            var currentUser = Common.UserUtitily.getUserProfile();
            var staffs = context.Staffs.Where(stf => stf.HotelId == currentUser.HotelId).ToList();
            for (int i = 0; i < staffs.Count(); i++ )
            {
                ConfigStaffData staffData = new ConfigStaffData();
                staffData.staff = staffs[i];
                staffData.staffUser = context.AspNetUsers.Where(usr => usr.Id == staffData.staff.UserId).FirstOrDefault();
                staffData.staffRoleId = context.AspNetUserRoles.Where(role => role.UserId == staffData.staffUser.Id).FirstOrDefault().RoleId;
                result.Add(staffData);
            }

            return result;
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Staff/CreateStaff")]
        public async Task<IHttpActionResult> CreateStaff(StaffViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var staffEmail = context.Staffs.Where(stf => stf.HotelId == currentClientUser.HotelId && stf.Email != "" && stf.Email == model.Email).FirstOrDefault();
            if (staffEmail != null)
            {
                ModelState.AddModelError("Message", "EMAIL_HAS_ALREADY_BEEN_TAKEN");
                return BadRequest(ModelState);
            }

            
            string StaffUserNameBaseOnHotelID = model.UserName + "@" + currentClientUser.HotelId;

            var staffUserName = context.AspNetUsers.Where(usr => usr.UserName == StaffUserNameBaseOnHotelID).FirstOrDefault();
            if (staffUserName != null)
            {
                ModelState.AddModelError("Message", "USER_NAME_HAS_ALREADY_BEEN_TAKEN");
                return BadRequest(ModelState);
            }
            string EmailNoConflict = model.UserName + "@ezcloud_" + currentClientUser.HotelId + ".vn";

            var user = new ApplicationUser()
            {
                UserName = StaffUserNameBaseOnHotelID,
                Email = EmailNoConflict
            };
           
            user.EmailConfirmed = true;
            
            user.DefaultHotelId = currentClientUser.HotelId;

            IdentityResult result = await UserManager.CreateAsync(user, model.Password);

            if (!result.Succeeded)
            {
                return GetErrorResult(result);
            }

            UserManager.AddToRole(user.Id, model.StaffRole);
            await UserManager.UpdateAsync(user);

            Staffs staffs = new Data.Staffs();
            staffs.UserId = user.Id;
            staffs.HotelId = currentClientUser.HotelId;
            staffs.Email = model.Email;
            staffs.StaffName = model.StaffName;
            staffs.Mobile = model.Mobile;
            staffs.IsActive = model.IsActive;
            staffs.Description = model.Description;
            context.Staffs.InsertOnSubmit(staffs);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            AspNetUsers staffUser = context.AspNetUsers.Where(usr => usr.Id == user.Id).FirstOrDefault();

            return Ok(new ConfigStaffData{
                        staff = staffs,
                        staffUser = staffUser
                    });
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Staff/GetStaffUserInfo")]
        public AspNetUsers getStaffUserInfo(int staffId)
        {

            
            var staff = context.Staffs.Where(stf => stf.StaffId == staffId).FirstOrDefault();
            return context.AspNetUsers.Where(user => user.Id == staff.UserId).FirstOrDefault();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Staff/SaveStaff")]
        public async Task<IHttpActionResult> SaveStaff(ConfigStaffData model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var staff = context.Staffs.Where(stf => stf.StaffId == model.staff.StaffId).FirstOrDefault();
            var user = context.AspNetUsers.Where(usr => usr.Id == model.staffUser.Id).FirstOrDefault();

            //var staffEmail = context.Staffs.Where(stf => stf.HotelId == currentClientUser.HotelId && stf.Email == model.staff.Email && stf.StaffId != model.staff.StaffId).FirstOrDefault();
            //if (staffEmail != null)
            //{
            //    ModelState.AddModelError("Message", "EMAIL_HAS_ALREADY_BEEN_TAKEN");
            //    return BadRequest(ModelState);
            //}

            //user.UserName = userNameTemp;
            var newPasswordHash = model.staffUser.PasswordHash;
            if (newPasswordHash != user.PasswordHash)
            {
                user.PasswordHash = System.Web.Helpers.Crypto.HashPassword(model.staffUser.PasswordHash);
            }
            //staff.Email = model.staff.Email;
            staff.StaffName = model.staff.StaffName;
            staff.Mobile = model.staff.Mobile;
            staff.Description = model.staff.Description;
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            var applicationUser = UserManager.FindById(user.Id);

            var currentUserRole = context.AspNetUserRoles.Where(userRl => userRl.UserId == model.staffUser.Id).FirstOrDefault();

            var currentRole = context.AspNetRoles.Where(role => role.Id == currentUserRole.RoleId).FirstOrDefault();

            UserManager.RemoveFromRole(user.Id, currentRole.Name);

            var userRole = context.AspNetRoles.Where(role => role.Id == model.staffRoleId).FirstOrDefault().Name;

            UserManager.AddToRole(applicationUser.Id, userRole);
            UserManager.UpdateAsync(applicationUser);

            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            //Remove session 
            UserSessionManager usm = new UserSessionManager();
            usm.SignOutUserId(staff.UserId);

            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("Staff/ChangeStaffStatus")]
        public async Task<IHttpActionResult> ChangeStaffStatus(int staffId)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            Staffs staffs = context.Staffs.Where(stf => stf.HotelId == currentClientUser.HotelId && stf.StaffId == staffId).FirstOrDefault();

            staffs.IsActive = (staffs.IsActive == true) ? false : true;

            context.SubmitChanges();

            //Remove session
            UserSessionManager usm = new UserSessionManager();
            usm.SignOutUserId(staffs.UserId);

            Common.Elastic.IndexLastAudit(context);
            return Ok();

        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/Money/GetAllMoney")]
        public List<Money> getAllMoney()
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            
            return context.Money.Where(money => money.HotelId == currentUser.HotelId).ToList();
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/Policies/RoomPricePolicies/GetRoomPricePolicies")]
        public RoomPrices GetRoomPricePolicies()
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            
            return context.RoomPrices.Where(rp => rp.HotelId == currentUser.HotelId).FirstOrDefault();
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/Plans/AddNewPlan")]
        public async Task<IHttpActionResult> AddNewPlan(NewPlan model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            RoomPrices roomPrices = new Data.RoomPrices();
            roomPrices.RoomPriceName = model.planName;
            roomPrices.HotelId = currentClientUser.HotelId;
            roomPrices.RoomTypeId = model.roomTypeId;
            roomPrices.Priority = model.priority;
            context.RoomPrices.InsertOnSubmit(roomPrices);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok(roomPrices);
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/Plans/SavePlanList")]
        public async Task<IHttpActionResult> SavePlanList(PlanListViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            List<RoomPrices> oldRoomPriceList = context.RoomPrices.Where(rp => rp.HotelId == currentClientUser.HotelId && rp.RoomTypeId == model.RoomType.RoomTypeId).ToList();

            for (int i = 0; i < model.PlanList.Count; i++)
            {
                    var planTemp = model.PlanList[i];
                    RoomPrices roomPrice = context.RoomPrices.Where(rp => rp.HotelId == currentClientUser.HotelId && rp.RoomPriceId == planTemp.RoomPriceId).FirstOrDefault();
                    var oldRoomPrice = oldRoomPriceList.FirstOrDefault(orp => orp.RoomPriceId == roomPrice.RoomPriceId);
                    if (oldRoomPrice != null)
                    {
                        oldRoomPrice.Priority = i;
                        oldRoomPrice.HotelId = currentClientUser.HotelId;
                        oldRoomPrice.RoomTypeId = planTemp.RoomTypeId;
                        oldRoomPrice.IsActive = planTemp.isActive;
                        oldRoomPrice.RoomPriceName = planTemp.RoomPriceName;
                        oldRoomPriceList.Remove(oldRoomPrice);
                    }
            }
            
            context.RoomPrices.DeleteAllOnSubmit(oldRoomPriceList);

            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok();
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/Plans/PlanPreviewCalculate")]
        public async Task<IHttpActionResult> PlanPreviewCalculate(PlanPreview model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            DateRange rangeInPreivew = new DateRange(model.previewStartDate, model.previewEndDate);
            DateRange rangeInSchedule = new DateRange(model.planDetailViewModel.PlanSchedule.startDate ?? default(DateTime), model.planDetailViewModel.PlanSchedule.endDate ?? default(DateTime));
            
            rangeInPreivew.model = model;
            rangeInPreivew.CalculateTimeDuration();
            rangeInPreivew.CalculateListFormula();
            rangeInPreivew.CalculateHourlyFormula();
            rangeInPreivew.CalculateTraveller();
            return Ok(rangeInPreivew);
        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/Plans/PlanListPreviewCalculate")]
        public IHttpActionResult PlanListPreviewCalculate(PlanListPreviewModel model)
        {
            
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            PlanListDateRange planListDateRange = new PlanListDateRange(model.previewStartDate, model.previewEndDate);
            planListDateRange.model = model;
            planListDateRange.CalculateTimeDuration();
            planListDateRange.CalculateConstantlyFormula();
            if (planListDateRange.totalHour * 60 >= planListDateRange.hotelTotalWorkTime)
            {
                planListDateRange.CalculateFullDayFormula();
            }
            else
            {
                planListDateRange.CalculateHourlyFormula();
            }
            
            planListDateRange.CalculateExtraAdultFormula();
            planListDateRange.CalculateExtraChildrenFormula();
            if (model.FOC == true)
            {
                planListDateRange.totalPrice = 0;
            }
            else
            {
                planListDateRange.CalculateDiscount();
            }
            return Ok(planListDateRange);

        }

        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("RoomTypes/Plans/SavePlanDetail")]
        public async Task<IHttpActionResult> SavePlanDetail(PlanDetailViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            int planId;

            if (model.Plan.RoomPriceId == null)
            {
                RoomPrices newRoomPrices = new Data.RoomPrices();
                newRoomPrices.RoomPriceName = model.Plan.RoomPriceName;
                newRoomPrices.RoomTypeId = model.Plan.RoomTypeId;
                newRoomPrices.Priority = model.Plan.Priority;
                newRoomPrices.IsActive = model.Plan.isActive;
                newRoomPrices.HotelId = currentClientUser.HotelId;
                newRoomPrices.UseHourlyPrice = model.UseHourlyPrice.isUsed;
                newRoomPrices.UseFullDayPrice = model.UseFullDayPrice.isUsed;
                newRoomPrices.FullDayPrice = model.UseFullDayPrice.price;
                newRoomPrices.UseEarlyCheckinFullday = model.UseEarlyCheckinFullDay.isUsed;
                newRoomPrices.UseDayNightPrice = model.UseDayNightPrice.isUsed;
                newRoomPrices.UseEarlyCheckinDayNight = model.UseEarlyCheckinDayNight.isUsed;
                newRoomPrices.DayNightPrice = model.UseDayNightPrice.price;
                newRoomPrices.UseWeeklyPrice = model.UseWeeklyPrice.isUsed;
                newRoomPrices.WeeklyPrice = model.UseWeeklyPrice.price;
                newRoomPrices.UseMonthlyPrice = model.UseMonthlyPrice.isUsed;
                newRoomPrices.MonthlyPrice = model.UseMonthlyPrice.price;
                newRoomPrices.UseExtraAdultPrice = model.UseExtraAdultPrice.isUsed;
                newRoomPrices.DefaultAdults = model.UseExtraAdultPrice.defaultAdults;
                newRoomPrices.ExtraAdultPrice = model.UseExtraAdultPrice.extraAdultPrice;
                newRoomPrices.UseExtraChildPrice = model.UseExtraChildPrice.isUsed;
                newRoomPrices.DefaultChildren = model.UseExtraChildPrice.defaultChildren;
                newRoomPrices.ExtraChildPrice = model.UseExtraChildPrice.extraChildPrice;
                newRoomPrices.ApplyOnMonday = model.PlanSchedule.ApplyOnMonday;
                newRoomPrices.ApplyOnTuesday = model.PlanSchedule.ApplyOnTuesday;
                newRoomPrices.ApplyOnWednesday = model.PlanSchedule.ApplyOnWednesday;
                newRoomPrices.ApplyOnThursday = model.PlanSchedule.ApplyOnThursday;
                newRoomPrices.ApplyOnFriday = model.PlanSchedule.ApplyOnFriday;
                newRoomPrices.ApplyOnSaturday = model.PlanSchedule.ApplyOnSaturday;
                newRoomPrices.ApplyOnSunday = model.PlanSchedule.ApplyOnSunday;
                newRoomPrices.StartDate = model.PlanSchedule.startDate;
                newRoomPrices.EndDate = model.PlanSchedule.endDate;
                
                context.RoomPrices.InsertOnSubmit(newRoomPrices);
                context.SubmitChanges();
                Common.Elastic.IndexLastAudit(context);
                planId = newRoomPrices.RoomPriceId;

                for (int i = 0; i < model.UseHourlyPrice.adjustment.Count; i++)
                {
                    RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                    newRoomPriceAdjustment.AdjustmentCode = model.UseHourlyPrice.adjustmentCode;
                    newRoomPriceAdjustment.Price = model.UseHourlyPrice.adjustment[i].Price;
                    newRoomPriceAdjustment.NumberOfHour = model.UseHourlyPrice.adjustment[i].NumberOfHour;
                    newRoomPriceAdjustment.RoomPriceId = newRoomPrices.RoomPriceId;
                    newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                    context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                    //context.SubmitChanges();
            //Common.Elastic.IndexLastAudit(context);
                }

                for (int i = 0; i < model.UseFullDayPrice.adjustment.Count; i++)
                {
                    RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                    newRoomPriceAdjustment.AdjustmentCode = model.UseFullDayPrice.adjustmentCode;
                    newRoomPriceAdjustment.Price = model.UseFullDayPrice.adjustment[i].Price;
                    newRoomPriceAdjustment.NumberOfHour = model.UseFullDayPrice.adjustment[i].NumberOfHour;
                    newRoomPriceAdjustment.RoomPriceId = newRoomPrices.RoomPriceId;
                    newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                    context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                    //context.SubmitChanges();
                    //Common.Elastic.IndexLastAudit(context);
                }

                for (int i = 0; i < model.UseEarlyCheckinFullDay.adjustment.Count; i++)
                {
                    RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                    newRoomPriceAdjustment.AdjustmentCode = model.UseEarlyCheckinFullDay.adjustmentCode;
                    newRoomPriceAdjustment.Price = model.UseEarlyCheckinFullDay.adjustment[i].Price;
                    newRoomPriceAdjustment.NumberOfHour = model.UseEarlyCheckinFullDay.adjustment[i].NumberOfHour;
                    newRoomPriceAdjustment.RoomPriceId = newRoomPrices.RoomPriceId;
                    newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                    context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                    //context.SubmitChanges();
                    //Common.Elastic.IndexLastAudit(context);
                }

                for (int i = 0; i < model.UseDayNightPrice.adjustment.Count; i++)
                {
                    RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                    newRoomPriceAdjustment.AdjustmentCode = model.UseDayNightPrice.adjustmentCode;
                    newRoomPriceAdjustment.Price = model.UseDayNightPrice.adjustment[i].Price;
                    newRoomPriceAdjustment.NumberOfHour = model.UseDayNightPrice.adjustment[i].NumberOfHour;
                    newRoomPriceAdjustment.RoomPriceId = newRoomPrices.RoomPriceId;
                    newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                    context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                    //context.SubmitChanges();
                    //Common.Elastic.IndexLastAudit(context);
                }

                for (int i = 0; i < model.UseEarlyCheckinDayNight.adjustment.Count; i++)
                {
                    RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                    newRoomPriceAdjustment.AdjustmentCode = model.UseEarlyCheckinDayNight.adjustmentCode;
                    newRoomPriceAdjustment.Price = model.UseEarlyCheckinDayNight.adjustment[i].Price;
                    newRoomPriceAdjustment.NumberOfHour = model.UseEarlyCheckinDayNight.adjustment[i].NumberOfHour;
                    newRoomPriceAdjustment.RoomPriceId = newRoomPrices.RoomPriceId;
                    newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                    context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                    //context.SubmitChanges();
                    //Common.Elastic.IndexLastAudit(context);
                }
            }

            else
            {
                RoomPrices oldRoomPrice = context.RoomPrices.Where(rp => rp.HotelId == currentClientUser.HotelId && rp.RoomTypeId == model.Plan.RoomTypeId && rp.RoomPriceId == model.Plan.RoomPriceId).FirstOrDefault();
                planId = oldRoomPrice.RoomPriceId;
                oldRoomPrice.RoomPriceName = model.Plan.RoomPriceName;
                oldRoomPrice.RoomTypeId = model.Plan.RoomTypeId;
                oldRoomPrice.Priority = model.Plan.Priority;
                oldRoomPrice.IsActive = model.Plan.isActive;
                oldRoomPrice.HotelId = currentClientUser.HotelId;
                oldRoomPrice.UseHourlyPrice = model.UseHourlyPrice.isUsed;
                oldRoomPrice.UseFullDayPrice = model.UseFullDayPrice.isUsed;
                oldRoomPrice.UseEarlyCheckinFullday = model.UseEarlyCheckinFullDay.isUsed;
                oldRoomPrice.FullDayPrice = model.UseFullDayPrice.price;
                oldRoomPrice.UseDayNightPrice = model.UseDayNightPrice.isUsed;
                oldRoomPrice.UseEarlyCheckinDayNight = model.UseEarlyCheckinDayNight.isUsed;
                oldRoomPrice.DayNightPrice = model.UseDayNightPrice.price;
                oldRoomPrice.UseWeeklyPrice = model.UseWeeklyPrice.isUsed;
                oldRoomPrice.WeeklyPrice = model.UseWeeklyPrice.price;
                oldRoomPrice.UseMonthlyPrice = model.UseMonthlyPrice.isUsed;
                oldRoomPrice.MonthlyPrice = model.UseMonthlyPrice.price;
                oldRoomPrice.UseExtraAdultPrice = model.UseExtraAdultPrice.isUsed;
                oldRoomPrice.DefaultAdults = model.UseExtraAdultPrice.defaultAdults;
                oldRoomPrice.ExtraAdultPrice = model.UseExtraAdultPrice.extraAdultPrice;
                oldRoomPrice.UseExtraChildPrice = model.UseExtraChildPrice.isUsed;
                oldRoomPrice.DefaultChildren = model.UseExtraChildPrice.defaultChildren;
                oldRoomPrice.ExtraChildPrice = model.UseExtraChildPrice.extraChildPrice;
                oldRoomPrice.ApplyOnMonday = model.PlanSchedule.ApplyOnMonday;
                oldRoomPrice.ApplyOnTuesday = model.PlanSchedule.ApplyOnTuesday;
                oldRoomPrice.ApplyOnWednesday = model.PlanSchedule.ApplyOnWednesday;
                oldRoomPrice.ApplyOnThursday = model.PlanSchedule.ApplyOnThursday;
                oldRoomPrice.ApplyOnFriday = model.PlanSchedule.ApplyOnFriday;
                oldRoomPrice.ApplyOnSaturday = model.PlanSchedule.ApplyOnSaturday;
                oldRoomPrice.ApplyOnSunday = model.PlanSchedule.ApplyOnSunday;
                oldRoomPrice.StartDate = model.PlanSchedule.startDate;
                oldRoomPrice.EndDate = model.PlanSchedule.endDate;
                
                List<RoomPriceAdjustment> oldHourlyPriceList = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == oldRoomPrice.RoomPriceId && rpa.AdjustmentCode == "HOURLY_PRICE").ToList();
                List<RoomPriceAdjustment> oldFullDayPriceList = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == oldRoomPrice.RoomPriceId && rpa.AdjustmentCode == "OVERDUE_FULLDAY").ToList();
                List<RoomPriceAdjustment> oldDayNightPriceList = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == oldRoomPrice.RoomPriceId && rpa.AdjustmentCode == "OVERDUE_DAYNIGHT").ToList();
                List<RoomPriceAdjustment> oldWeeklyPriceList = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == oldRoomPrice.RoomPriceId && rpa.AdjustmentCode == "OVERDUE_WEEKLY").ToList();
                List<RoomPriceAdjustment> oldMonthlyPriceList = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == oldRoomPrice.RoomPriceId && rpa.AdjustmentCode == "OVERDUE_MONTHLY").ToList();
                List<RoomPriceAdjustment> oldEarlyCheckinFullDayList = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == oldRoomPrice.RoomPriceId && rpa.AdjustmentCode == "EARLY_CHECKIN_FULL_DAY").ToList();
                List<RoomPriceAdjustment> oldEarlyCheckinDayNightList = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == oldRoomPrice.RoomPriceId && rpa.AdjustmentCode == "EARLY_CHECKIN_DAY_NIGHT").ToList();

                //USE HOURLY PRICE
                for (int i = 0; i < model.UseHourlyPrice.adjustment.Count; i++)
                {
                    RoomPriceAdjustment oldHourlyPrice = null;
                    RoomPriceAdjustment roomPriceAdjustment = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == model.UseHourlyPrice.adjustment[i].RoomPriceId && rpa.RoomPriceAdjustmentId == model.UseHourlyPrice.adjustment[i].RoomPriceAdjustmentId).FirstOrDefault();
                    if (roomPriceAdjustment != null)
                    {
                        oldHourlyPrice = oldHourlyPriceList.FirstOrDefault(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId);
                    }
                    if (oldHourlyPrice != null)
                    {
                        oldHourlyPrice.AdjustmentCode = model.UseHourlyPrice.adjustmentCode;
                        oldHourlyPrice.Price = model.UseHourlyPrice.adjustment[i].Price;
                        oldHourlyPrice.NumberOfHour = model.UseHourlyPrice.adjustment[i].NumberOfHour;
                        oldHourlyPrice.RoomPriceId = oldRoomPrice.RoomPriceId;
                        oldHourlyPrice.HotelId = currentClientUser.HotelId;
                        oldHourlyPriceList.Remove(oldHourlyPrice);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }
                    
                    else
                    {
                        RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                        newRoomPriceAdjustment.AdjustmentCode = model.UseHourlyPrice.adjustmentCode;
                        newRoomPriceAdjustment.Price = model.UseHourlyPrice.adjustment[i].Price;
                        newRoomPriceAdjustment.NumberOfHour = model.UseHourlyPrice.adjustment[i].NumberOfHour;
                        newRoomPriceAdjustment.RoomPriceId = oldRoomPrice.RoomPriceId;
                        newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                        context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }

                }
                context.RoomPriceAdjustment.DeleteAllOnSubmit(oldHourlyPriceList);


                //USE FULL DAY PRICE
                for (int i = 0; i < model.UseFullDayPrice.adjustment.Count; i++)
                {
                    RoomPriceAdjustment oldFullDayPrice = null;
                    RoomPriceAdjustment roomPriceAdjustment = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == model.UseFullDayPrice.adjustment[i].RoomPriceId && rpa.RoomPriceAdjustmentId == model.UseFullDayPrice.adjustment[i].RoomPriceAdjustmentId).FirstOrDefault();
                    if (roomPriceAdjustment != null)
                    {
                        oldFullDayPrice = oldFullDayPriceList.FirstOrDefault(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId);
                    }
                    //var oldFullDayPrice = oldFullDayPriceList.FirstOrDefault(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId);
                    if (oldFullDayPrice != null)
                    {
                        oldFullDayPrice.AdjustmentCode = model.UseFullDayPrice.adjustmentCode;
                        oldFullDayPrice.Price = model.UseFullDayPrice.adjustment[i].Price;
                        oldFullDayPrice.NumberOfHour = model.UseFullDayPrice.adjustment[i].NumberOfHour;
                        oldFullDayPrice.RoomPriceId = oldRoomPrice.RoomPriceId;
                        oldFullDayPrice.HotelId = currentClientUser.HotelId;
                        oldFullDayPriceList.Remove(oldFullDayPrice);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }
                   
                    else
                    {
                        RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                        newRoomPriceAdjustment.AdjustmentCode = model.UseFullDayPrice.adjustmentCode;
                        newRoomPriceAdjustment.Price = model.UseFullDayPrice.adjustment[i].Price;
                        newRoomPriceAdjustment.NumberOfHour = model.UseFullDayPrice.adjustment[i].NumberOfHour;
                        newRoomPriceAdjustment.RoomPriceId = oldRoomPrice.RoomPriceId;
                        newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                        context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }

                }
                context.RoomPriceAdjustment.DeleteAllOnSubmit(oldFullDayPriceList);


                //USE EARLY CHECK IN FULL DAY
                for (int i = 0; i < model.UseEarlyCheckinFullDay.adjustment.Count; i++)
                {
                    RoomPriceAdjustment oldEarlyCheckinFullDay = null;
                    RoomPriceAdjustment roomPriceAdjustment = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == model.UseEarlyCheckinFullDay.adjustment[i].RoomPriceId && rpa.RoomPriceAdjustmentId == model.UseEarlyCheckinFullDay.adjustment[i].RoomPriceAdjustmentId).FirstOrDefault();
                    if (roomPriceAdjustment != null)
                    {
                        oldEarlyCheckinFullDay = oldEarlyCheckinFullDayList.FirstOrDefault(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId);
                    }
                    //var oldEarlyCheckinFullDay = oldEarlyCheckinFullDayList.FirstOrDefault(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId);
                    if (oldEarlyCheckinFullDay != null)
                    {
                        oldEarlyCheckinFullDay.AdjustmentCode = model.UseEarlyCheckinFullDay.adjustmentCode;
                        oldEarlyCheckinFullDay.Price = model.UseEarlyCheckinFullDay.adjustment[i].Price;
                        oldEarlyCheckinFullDay.NumberOfHour = model.UseEarlyCheckinFullDay.adjustment[i].NumberOfHour;
                        oldEarlyCheckinFullDay.RoomPriceId = oldRoomPrice.RoomPriceId;
                        oldEarlyCheckinFullDay.HotelId = currentClientUser.HotelId;
                        oldEarlyCheckinFullDayList.Remove(oldEarlyCheckinFullDay);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }
                    
                    else
                    {
                        RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                        newRoomPriceAdjustment.AdjustmentCode = model.UseEarlyCheckinFullDay.adjustmentCode;
                        newRoomPriceAdjustment.Price = model.UseEarlyCheckinFullDay.adjustment[i].Price;
                        newRoomPriceAdjustment.NumberOfHour = model.UseEarlyCheckinFullDay.adjustment[i].NumberOfHour;
                        newRoomPriceAdjustment.RoomPriceId = oldRoomPrice.RoomPriceId;
                        newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                        context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }

                }
                context.RoomPriceAdjustment.DeleteAllOnSubmit(oldEarlyCheckinFullDayList);

                //USE DAY NIGHT PRICE
                for (int i = 0; i < model.UseDayNightPrice.adjustment.Count; i++)
                {
                    RoomPriceAdjustment oldDayNightPrice = null;
                    RoomPriceAdjustment roomPriceAdjustment = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == model.UseDayNightPrice.adjustment[i].RoomPriceId && rpa.RoomPriceAdjustmentId == model.UseDayNightPrice.adjustment[i].RoomPriceAdjustmentId).FirstOrDefault();
                    if (roomPriceAdjustment != null)
                    {
                        oldDayNightPrice = oldDayNightPriceList.Where(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId).FirstOrDefault();
                    }
                    //var oldDayNightPrice = oldDayNightPriceList.Where(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId).FirstOrDefault();
                    if (oldDayNightPrice != null)
                    {
                        oldDayNightPrice.AdjustmentCode = model.UseDayNightPrice.adjustmentCode;
                        oldDayNightPrice.Price = model.UseDayNightPrice.adjustment[i].Price;
                        oldDayNightPrice.NumberOfHour = model.UseDayNightPrice.adjustment[i].NumberOfHour;
                        oldDayNightPrice.RoomPriceId = oldRoomPrice.RoomPriceId;
                        oldDayNightPrice.HotelId = currentClientUser.HotelId;
                        oldDayNightPriceList.Remove(oldDayNightPrice);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }
                   
                    else
                    {
                        RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                        newRoomPriceAdjustment.AdjustmentCode = model.UseDayNightPrice.adjustmentCode;
                        newRoomPriceAdjustment.Price = model.UseDayNightPrice.adjustment[i].Price;
                        newRoomPriceAdjustment.NumberOfHour = model.UseDayNightPrice.adjustment[i].NumberOfHour;
                        newRoomPriceAdjustment.RoomPriceId = oldRoomPrice.RoomPriceId;
                        newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                        context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }

                }

                context.RoomPriceAdjustment.DeleteAllOnSubmit(oldDayNightPriceList);

                //USE EARLY CHECK IN DAY NIGHT
                for (int i = 0; i < model.UseEarlyCheckinDayNight.adjustment.Count; i++)
                {
                    RoomPriceAdjustment roomPriceAdjustment = context.RoomPriceAdjustment.Where(rpa => rpa.HotelId == currentClientUser.HotelId && rpa.RoomPriceId == model.UseEarlyCheckinDayNight.adjustment[i].RoomPriceId && rpa.RoomPriceAdjustmentId == model.UseEarlyCheckinDayNight.adjustment[i].RoomPriceAdjustmentId).FirstOrDefault();
                    RoomPriceAdjustment oldEarlyCheckinDayNight = null;
                    if (roomPriceAdjustment != null)
                    {
                        oldEarlyCheckinDayNight = oldEarlyCheckinDayNightList.FirstOrDefault(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId);
                    }
                    //var oldEarlyCheckinDayNight = oldEarlyCheckinDayNightList.FirstOrDefault(old => old.RoomPriceAdjustmentId == roomPriceAdjustment.RoomPriceAdjustmentId);
                    if (oldEarlyCheckinDayNight != null)
                    {
                        oldEarlyCheckinDayNight.AdjustmentCode = model.UseEarlyCheckinDayNight.adjustmentCode;
                        oldEarlyCheckinDayNight.Price = model.UseEarlyCheckinDayNight.adjustment[i].Price;
                        oldEarlyCheckinDayNight.NumberOfHour = model.UseEarlyCheckinDayNight.adjustment[i].NumberOfHour;
                        oldEarlyCheckinDayNight.RoomPriceId = oldRoomPrice.RoomPriceId;
                        oldEarlyCheckinDayNight.HotelId = currentClientUser.HotelId;
                        oldEarlyCheckinDayNightList.Remove(oldEarlyCheckinDayNight);
                        //context.SubmitChanges();
                        //Common.Elastic.IndexLastAudit(context);
                    }
                    
                    else
                    {
                        RoomPriceAdjustment newRoomPriceAdjustment = new Data.RoomPriceAdjustment();
                        newRoomPriceAdjustment.AdjustmentCode = model.UseEarlyCheckinDayNight.adjustmentCode;
                        newRoomPriceAdjustment.Price = model.UseEarlyCheckinDayNight.adjustment[i].Price;
                        newRoomPriceAdjustment.NumberOfHour = model.UseEarlyCheckinDayNight.adjustment[i].NumberOfHour;
                        newRoomPriceAdjustment.RoomPriceId = oldRoomPrice.RoomPriceId;
                        newRoomPriceAdjustment.HotelId = currentClientUser.HotelId;
                        context.RoomPriceAdjustment.InsertOnSubmit(newRoomPriceAdjustment);
                        //context.SubmitChanges();
                       // Common.Elastic.IndexLastAudit(context);
                    }
                }
                context.RoomPriceAdjustment.DeleteAllOnSubmit(oldEarlyCheckinDayNightList);


            }
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok(planId);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/GetAllSystemData")]
        public ConfigSystemData gettAllSystemData()
        {
            var currentUser = Common.UserUtitily.getUserProfile();
            var moneys = context.Money.Where(mon => mon.HotelId == currentUser.HotelId).ToList();
            var currencies = context.Currencies.Where(cur => cur.CurrencyId == cur.CurrencyId).ToList();
            var statusColorList = context.StatusColors.Where(sc => sc.HotelId == currentUser.HotelId).ToList();
            int currentHotelDefaultMoneyId = context.Hotels.Where(ht => ht.HotelId == currentUser.HotelId).FirstOrDefault().DefaultMoneyId ?? default(int);
            var currentHotel = context.Hotels.Where(ht => ht.HotelId == currentUser.HotelId).FirstOrDefault();
            int minutesToRoundUp = currentHotel.MinutesToRoundUp;
            var isRoomDirtyAfterNightAudit = currentHotel.IsRoomDirtyAfterNighAudit;
            int timeZoneOffset = currentHotel.TimeZoneOffset;
            string timeZoneId = currentHotel.TimeZoneId;
            var hotelFormRoomInvoice = context.HotelForm.Where(hf => hf.HotelId == currentHotel.HotelId && hf.FormType == "RoomInvoice").FirstOrDefault();
            var hotelFormRoomReceipt = context.HotelForm.Where(hf => hf.HotelId == currentHotel.HotelId && hf.FormType == "Receipt").FirstOrDefault();
            var HotelTimeInOut = context.Hotels.Where(m => m.HotelId == currentHotel.HotelId).FirstOrDefault();
            ReadOnlyCollection<TimeZoneInfo> tz;
            tz = TimeZoneInfo.GetSystemTimeZones();
            var connectivities = new List<HotelConnectivity>();
            var connectivityModuleList = context.HotelConnectivityModuleCode.Where(hcm => hcm.HotelConnectivityModuleCodeId == hcm.HotelConnectivityModuleCodeId).ToList();
            
            foreach(var module in connectivityModuleList)
            {
                var isUsed = false;
                var IsInputCardToCheckout = false;
                bool IsAutomaticalAddHourCheckout = false;
                int HourAddToCheckout = 0;
                var connectivityConfig = context.HotelConnectivityModuleConfig.Where(hc => hc.HotelId == currentUser.HotelId && hc.HotelConnectivityModuleCodeId == module.HotelConnectivityModuleCodeId).FirstOrDefault();

                if (connectivityConfig != null)
                {
                    IsInputCardToCheckout = connectivityConfig.IsInputCardToCheckout == null ? false : connectivityConfig.IsInputCardToCheckout.Value;
                    isUsed = true;
                    IsAutomaticalAddHourCheckout = connectivityConfig.IsAutomaticalAddHourCheckout == null ? false : connectivityConfig.IsAutomaticalAddHourCheckout.Value;
                    HourAddToCheckout = connectivityConfig.HourAddToCheckout == null ? 0 : connectivityConfig.HourAddToCheckout.Value;
                }
                HotelConnectivity conn = new HotelConnectivity();
                conn.code = module;
                conn.isUsed = isUsed;
                conn.IsInputCardToCheckout = IsInputCardToCheckout;
                conn.IsAutomaticalAddHourCheckout = IsAutomaticalAddHourCheckout;
                conn.HourAddToCheckout = HourAddToCheckout;
                connectivities.Add(conn);
            }

            return new ConfigSystemData
            {
                currentHotelDefaultMoneyId = currentHotelDefaultMoneyId,
                moneys = moneys,
                currencies = currencies,
                statusColorList = statusColorList,
                hotelFormRoomReceipt = hotelFormRoomReceipt,
                hotelFormRoomInvoice = hotelFormRoomInvoice,
                hotelTimeSetting = new HotelTimeSetting
                {
                    FullDayCheckoutTime = currentHotel.FullDayCheckoutTime,
                    FullDayCheckinTime = currentHotel.FullDayCheckinTime,
                    UseDayNightSetting = currentHotel.UseDayNightSetting,
                    DayNightStartTime = currentHotel.DayNightStartTime,
                    DayNightEndTime = currentHotel.DayNightEndTime,
                    MinutesToRoundUp = minutesToRoundUp,
                    TimeZoneId = timeZoneId,
                    IsRoomDirtyAfterNightAudit = isRoomDirtyAfterNightAudit,
                    listTimeZone = tz,
                    UseTimeInOutPrivate = HotelTimeInOut.IsUseTimeInOutPrivate == null ? false : HotelTimeInOut.IsUseTimeInOutPrivate.Value,
                    TimeInPrivate = HotelTimeInOut.TimeInPrivate == null ? new TimeSpan(12, 00, 00) : HotelTimeInOut.TimeInPrivate.Value,
                    TimeOutPrivate = HotelTimeInOut.TimeOutPrivate == null ? new TimeSpan(12, 00, 00) : HotelTimeInOut.TimeOutPrivate.Value,
                },
                connectivities = connectivities
            };
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/SaveCurrencyList")]
        public async Task<IHttpActionResult> SaveCurrencyList(CurrencyModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();

            List<Money> oldCurrencyList = context.Money.Where(mon => mon.HotelId == currentClientUser.HotelId).ToList();
            List<Money> newCurrencyList = new List<Money>();
            for (int i = 0; i < model.currencyList.Count(); i++)
            {
                var currency = context.Money.Where(mon => mon.HotelId == currentClientUser.HotelId && mon.MoneyId == model.currencyList[i].MoneyId).FirstOrDefault();
                if (currency != null)
                { 
                    var oldCurrency = oldCurrencyList.FirstOrDefault(oc => oc.MoneyId == currency.MoneyId);
                    if (oldCurrency != null)
                    {
                        oldCurrency.MoneyName = model.currencyList[i].MoneyName;
                        oldCurrency.ExchangeRate = model.currencyList[i].ExchangeRate;
                        oldCurrency.Description = model.currencyList[i].Description;
                        oldCurrencyList.Remove(oldCurrency);
                    }
                } 
                    
                else
                {
                    Money newMoney = new Money();
                    newMoney.MoneyName = model.currencyList[i].MoneyName;
                    newMoney.ExchangeRate = model.currencyList[i].ExchangeRate;
                    //newMoney.ExchangeRate = EnhancedMath.RoundUp(newMoney.ExchangeRate, 3);
                    newMoney.Description = model.currencyList[i].Description;
                    newMoney.CurrencyId = model.currencyList[i].CurrencyId;
                    newMoney.HotelId = currentClientUser.HotelId;
                    context.Money.InsertOnSubmit(newMoney);
                    if (i == model.index)
                    {
                        context.SubmitChanges();
                        Common.Elastic.IndexLastAudit(context);
                        model.currencyList[model.index].MoneyId = newMoney.MoneyId;
                    }
                    newCurrencyList.Add(newMoney);

                }
            }
            context.Money.DeleteAllOnSubmit(oldCurrencyList);
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            Hotels hotel = context.Hotels.Where(ht => ht.HotelId == currentClientUser.HotelId).FirstOrDefault();
            hotel.DefaultMoneyId = model.currencyList[model.index].MoneyId;
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok(new{
                currentHotelDefaultMoneyId = hotel.DefaultMoneyId,
                newCurrencyList = newCurrencyList
            });
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/SaveStatusColorList")]
        public async Task<IHttpActionResult> SaveStatusColorList(StatusColor[] model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            for (int i = 0; i < model.Count(); i++)
            {
                var oldStatusColor = context.StatusColors.Where(sc => sc.HotelId == currentClientUser.HotelId && sc.StatusColorId == model[i].StatusColorId).FirstOrDefault();
                if (oldStatusColor != null)
                {
                    oldStatusColor.ColorCode = model[i].ColorCode;
                }
            }
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/SaveHotelTimeSetting")]
        public async Task<IHttpActionResult> SaveHotelTimeSetting(HotelTimeSetting model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var hotel = context.Hotels.Where(ht => ht.HotelId == currentClientUser.HotelId).FirstOrDefault();
            hotel.FullDayCheckoutTime = model.FullDayCheckoutTime ?? default(TimeSpan);
            hotel.FullDayCheckinTime = model.FullDayCheckinTime ?? default(TimeSpan);
            hotel.UseDayNightSetting = model.UseDayNightSetting;
            hotel.DayNightStartTime = model.DayNightStartTime;
            hotel.DayNightEndTime = model.DayNightEndTime;
            hotel.NightAuditTime = model.NightAuditTime;
            hotel.MinutesToRoundUp = model.MinutesToRoundUp;
            hotel.IsRoomDirtyAfterNighAudit = model.IsRoomDirtyAfterNightAudit;
            //hotel.TimeZoneOffset = model.TimeZoneOffset;
            hotel.TimeZoneId = model.TimeZoneId;
            TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(model.TimeZoneId);
            TimeSpan offset = tzi.BaseUtcOffset;
            hotel.TimeZoneOffset = (int)offset.TotalMinutes;
            if (model.UseTimeInOutPrivate.Value)
            {
                hotel.IsUseTimeInOutPrivate = model.UseTimeInOutPrivate.Value;
                hotel.TimeInPrivate = model.TimeInPrivate.Value;
                hotel.TimeOutPrivate = model.TimeOutPrivate.Value;
            }
            else
            {
                hotel.IsUseTimeInOutPrivate = false;
            }
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/SaveHotelFormRoomInvoice")]
        public async Task<IHttpActionResult> SaveHotelFormRoomInvoice(List<HotelForm> model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var hotel = context.Hotels.Where(ht => ht.HotelId == currentClientUser.HotelId).FirstOrDefault();

            var hotelFormRoomInvocie = context.HotelForm.Where(hf => hf.HotelId == currentClientUser.HotelId && hf.FormType == "RoomInvoice").FirstOrDefault();
            if (hotelFormRoomInvocie==null)
            {
                HotelForm hotelform = new HotelForm();
                hotelform.HotelId = currentClientUser.HotelId;
                hotelform.FormType = "RoomInvoice";
                hotelform.Value = "A4";
                context.HotelForm.InsertOnSubmit(hotelform);
                context.SubmitChanges();
                Common.Elastic.IndexLastAudit(context);

                // thiet lap mac dinh cho in dat coc
                var hotelFormRoomReceive = context.HotelForm.Where(hf => hf.HotelId == currentClientUser.HotelId && hf.FormType == "Receipt").FirstOrDefault();
                if (hotelFormRoomReceive==null)
                {
                    HotelForm hotelformR = new HotelForm();
                    hotelformR.HotelId = currentClientUser.HotelId;
                    hotelformR.FormType = "Receipt";
                    hotelformR.Value = "A4";
                    context.HotelForm.InsertOnSubmit(hotelformR);
                    context.SubmitChanges();
                    Common.Elastic.IndexLastAudit(context);
                }

            }
            else
            {
                hotelFormRoomInvocie.Value = model[0].Value;
                var hotelFormRoomReceipt= context.HotelForm.Where(hf => hf.HotelId == currentClientUser.HotelId && hf.FormType == "Receipt").FirstOrDefault();
                if (hotelFormRoomReceipt != null)
                {
                    hotelFormRoomReceipt.Value = model[1].Value;
                }
                context.SubmitChanges();
                Common.Elastic.IndexLastAudit(context);
                
            }
           
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("System/SaveConnectivitiesSetting")]
        public async Task<IHttpActionResult> SaveConnectivitiesSetting(List<HotelConnectivity> model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();

            if (model.Count > 0)
            {
                for(int i=0;i<model.Count;i++)
                {
                    var conn = model[i];
                    var connectivityConfig = context.HotelConnectivityModuleConfig.Where(cn => cn.HotelId == currentClientUser.HotelId && cn.HotelConnectivityModuleCodeId == conn.code.HotelConnectivityModuleCodeId).FirstOrDefault();
                    if (connectivityConfig != null)
                    {
                        if (!conn.isUsed)
                        {
                            context.HotelConnectivityModuleConfig.DeleteOnSubmit(connectivityConfig);
                            context.SubmitChanges();
                            Common.Elastic.IndexLastAudit(context);
                        }else
                        {
                            connectivityConfig.IsInputCardToCheckout = conn.IsInputCardToCheckout;
                            connectivityConfig.IsAutomaticalAddHourCheckout = conn.IsAutomaticalAddHourCheckout;
                            connectivityConfig.HourAddToCheckout = conn.HourAddToCheckout;
                            context.SubmitChanges();
                            Common.Elastic.IndexLastAudit(context);
                        }
                    }
                    else
                    {
                        if (conn.isUsed)
                        {
                            HotelConnectivityModuleConfig config = new HotelConnectivityModuleConfig();
                            config.HotelId = currentClientUser.HotelId;
                            config.HotelConnectivityModuleCodeId = conn.code.HotelConnectivityModuleCodeId;
                            config.IsInputCardToCheckout = conn.IsInputCardToCheckout;
                            config.IsAutomaticalAddHourCheckout = conn.IsAutomaticalAddHourCheckout;
                            config.HourAddToCheckout = conn.HourAddToCheckout;
                            context.HotelConnectivityModuleConfig.InsertOnSubmit(config);
                            context.SubmitChanges();
                            Common.Elastic.IndexLastAudit(context);
                        }
                    }
                }
            }
            
            
            return Ok();
        }

        //
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        private IHttpActionResult GetErrorResult(IdentityResult result)
        {
            if (result == null)
            {
                return InternalServerError();
            }

            if (!result.Succeeded)
            {
                if (result.Errors != null)
                {
                    foreach (string error in result.Errors)
                    {
                        ModelState.AddModelError("", error);
                    }


                    if (ModelState.IsValid)
                    {
                        // No ModelState errors are available to send, so just return an empty BadRequest.
                        return BadRequest();
                    }

                    return BadRequest(ModelState);
                }
            }
            return null;
        }

        #region Hotel Owner Info - loinq
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HttpGet]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("getHotelOwnerInfo")]
        public async Task<IHttpActionResult> getHotelOwnerInfo(string email) {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var hotelOwer = context.Hotels.Where(m => m.HotelId == currentClientUser.HotelId).Single();
            string EmailHotelOwner = context.AspNetUsers.Where(m => m.Id == hotelOwer.HotelOwnerId).Single().Email;
            var hotelInfo = context.HotelOwners.Where(m => m.UserId == hotelOwer.HotelOwnerId).Select(m => new ConfigHotelOwner
            {
                HotelOwnerId = m.HotelOwnerId,
                Fullname = m.FullName,
                Email = EmailHotelOwner,
                Address = m.Address,
                Phone = m.Phone,
                HotelSizeId = m.HotelSizeId,
                NumberOfHotels = m.NumberOfHotels
            }).Single();
            return Ok(hotelInfo);
        }

        [HttpPost]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("UpdateHotelOwnerInfo")]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        public async Task<IHttpActionResult> updateHotelOwnerInfo(ConfigHotelOwner model)
        {
            if (model == null)
            {
                return BadRequest("HOTEL_OWNER_IS_NULL");
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var hotelOwer = context.Hotels.Where(m => m.HotelId == currentClientUser.HotelId).Single();
            HotelOwners data=context.HotelOwners.Where(o => o.UserId == hotelOwer.HotelOwnerId ).FirstOrDefault();
            if (data != null)
            {
                data.HotelSizeId = model.HotelSizeId;
                data.FullName = model.Fullname;
                data.Address = model.Address;
                data.Phone = model.Phone;
                data.NumberOfHotels = model.NumberOfHotels;
            }
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            return Ok("Success");
        }

        [HttpPost]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("UpdateEmailHotelOwnerInfo")]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER")]
        public async Task<IHttpActionResult> updateEmailHotelOwnerInfo(ConfigEmailHotelOwner model)
        {
            if (model == null)
            {
                return BadRequest("HOTEL_OWNER_IS_NULL");
            }

            var currentClientUser = Common.UserUtitily.getUserProfile();

            var user = await UserManager.FindByNameAsync(User.Identity.GetUserName());
            var result = await UserManager.CheckPasswordAsync(user, model.OldPassword);
            if (result==false)
            {
                return BadRequest("OLD_PASSWORD_INCORRECT");
            }
           

            var checkEmailExists = context.AspNetUsers.Where(e => e.Email == model.NewEmail).ToList();
            if (checkEmailExists!=null && checkEmailExists.Count>0)
            {
                return BadRequest("YOUR_EMAIL_ADDRESS_ALREADY_IN_USE");
            }
           
            var hotelOwer = context.Hotels.Where(m => m.HotelId == currentClientUser.HotelId).Single();
            var data = context.AspNetUsers.Where(o => o.Id == hotelOwer.HotelOwnerId).FirstOrDefault();
            var oldEmail = "";
            if (data != null)
            {
                oldEmail = data.Email;
                data.Email = model.NewEmail;
                data.UserName = model.NewEmail;
            }
            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);
            //var currentUser = context.AspNetUsers.FirstOrDefault(usr => usr.Id == hotel.HotelOwnerId);
            //Send an email to New email address
            string subject = "Changing hotel owner email/Thay đổi địa chỉ email chủ khách sạn";
            EmailSender.SendEmailChangeEmailHotelOwner(model.NewEmail, subject, model.NewEmail, model.NewEmail, oldEmail);
            //Send an email to old email address
            EmailSender.SendEmailChangeEmailHotelOwnerToOldOwner(oldEmail, subject, oldEmail, model.NewEmail, oldEmail);

            return Ok("EDIT_EMAIL_HOTEL_OWNER_SUCCESSFUL");
        }
        #endregion

        #region Room view Template - loinq
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("saveHotelDisplay")]
        public async Task<IHttpActionResult> saveDisplays(List<HotelDisplays> model)
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            context.HotelDisplays.DeleteAllOnSubmit(context.HotelDisplays.Where(m => m.HotelId == currentClientUser.HotelId));
            context.SubmitChanges();
            foreach (var item in model)
            {
                HotelDisplays hd = new HotelDisplays();
                hd.HotelId = currentClientUser.HotelId;
                hd.DisplayGroupDetailId = item.DisplayGroupDetailId;
                hd.DisplayGroupId = item.DisplayGroupId;
                hd.DisplayGroupPriority = item.DisplayGroupPriority;
                hd.DisplayGroupDetailPriority = item.DisplayGroupDetailPriority;
                context.HotelDisplays.InsertOnSubmit(hd);
            };
            context.SubmitChanges();
            return Ok();
        }
        #endregion

        #region Floor List - loinq
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("getAllFloor")]
        public async Task<IHttpActionResult> getAllFloor()
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var FloorList = context.Floors.Where(f => f.HotelId == currentClientUser.HotelId && f.IsDeleted == false).Select(s => new {
                s.FloorId,
                s.FloorName,
                s.FloorDescription,
                s.ModifiedDate,
                s.ModifiedUserId,
                s.IsActive,
                //IsActive = s.IsActive == null ? false : s.IsActive,
                s.HotelId,
                s.OrderNumber,
            }).ToList();
            return Ok(FloorList);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("AddNewFloor")]
        public async Task<IHttpActionResult> AddNewFloor(Floors model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            int orderNumber = 0;
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var Floor = context.Floors.Where(f => f.HotelId == currentClientUser.HotelId).OrderByDescending(o => o.OrderNumber).FirstOrDefault();
            if(Floor != null)
            {
                orderNumber = Floor.OrderNumber.Value + 1;
            }
            model.HotelId = currentClientUser.HotelId;
            model.CreatedDate = DateTime.UtcNow;
            model.CreatedUserId = currentClientUser.UserId;
            model.IsDeleted = false;
            model.IsActive = true;
            model.OrderNumber = orderNumber;
            context.Floors.InsertOnSubmit(model);
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok(model.FloorId);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("EditFloor")]
        public async Task<IHttpActionResult> EditFloor(Floors model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var currentFloor = context.Floors.Where(f => f.HotelId == currentClientUser.HotelId && f.FloorId == model.FloorId).FirstOrDefault();
            if(currentFloor == null)
            {
                return BadRequest("FLOOR_IS_NOT_EXISTS");
            }
            currentFloor.FloorName = model.FloorName;
            currentFloor.FloorDescription = model.FloorDescription;
            currentFloor.ModifiedDate = DateTime.UtcNow;
            currentFloor.ModifiedUserId = currentClientUser.UserId;
            //currentFloor.OrderNumber = model.OrderNumber == null ? 0 : model.OrderNumber;
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok(model.FloorId);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ChangeFloorStatus")]
        public async Task<IHttpActionResult> ChangeFloorStatus(int FloorId)
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var floor = context.Floors.Where(f => f.HotelId == currentClientUser.HotelId && f.FloorId == FloorId && f.IsDeleted == false).FirstOrDefault();
            if(floor == null)
            {
                return BadRequest("FLOOR_IS_NOT_EXISTS");
            }
            floor.IsActive = (floor.IsActive == true) ? false : true;
            floor.ModifiedDate = DateTime.UtcNow;
            floor.ModifiedUserId = currentClientUser.UserId;
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok();
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("GetAllRoomByFloor")]
        public async Task<IHttpActionResult> GetAllRoomByFloor(int FloorId)
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            List<Rooms> rooms = context.Rooms.Where(r => r.HotelId == currentClientUser.HotelId && r.FloorId == FloorId && r.Floors.IsDeleted == false).ToList();
            return Ok(rooms);
        }
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ChangeFloorsOrderNumber")]
        public async Task<IHttpActionResult> ChangeFloorsOrderNumber(List<Floors> model)
        {
            if(!ModelState.IsValid || model.Count() == 0)
            {
                return BadRequest(ModelState);
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();
            foreach (Floors floor in model)
            {
                var currentFloor = context.Floors.Where(f => f.HotelId == currentClientUser.HotelId && f.FloorId == floor.FloorId).FirstOrDefault();
                if(currentFloor != null)
                {
                    currentFloor.OrderNumber = floor.OrderNumber == null ? 0 : floor.OrderNumber;
                }
            }
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok();
        }
        [HttpGet]
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("DeleteFloor")]
        public async Task<IHttpActionResult> DeleteFloor(int floorId)
        {
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var floor = context.Floors.Where(f => f.HotelId == currentClientUser.HotelId && f.FloorId == floorId).FirstOrDefault();
            if(floor == null)
            {
                return BadRequest("FLOOR_IS_NOT_EXISTS");
            }
            var roomsInFloor = context.Rooms.Where(r => r.HotelId == currentClientUser.HotelId && r.FloorId == floorId && r.IsDeleted == false).ToList();
            if(roomsInFloor.Count() > 0)
            {
                return BadRequest("CAN_NOT_DELETE_FLOOR.PLEASE_PROCESS_ALL_ROOMS_IN_FLOOR");
            }
            floor.IsDeleted = true;
            floor.DeletedDate = DateTime.UtcNow;
            floor.DeletedUserId = currentClientUser.UserId;
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok();
        }
        #endregion

        #region Change RoomType Order Number 
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ChangeRoomTypesOrderNumber")]
        public async Task<IHttpActionResult> ChangeRoomTypesOrderNumber(List<RoomTypes> model)
        {
            if(!ModelState.IsValid || model.Count() == 0)
            {
                return BadRequest(ModelState);
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();
            foreach (RoomTypes rt in model)
            {
                var currentRoomType = context.RoomTypes.Where(rType => rType.HotelId == currentClientUser.HotelId && rType.RoomTypeId == rt.RoomTypeId).FirstOrDefault();
                if(currentRoomType != null)
                {
                    currentRoomType.OrderNumber = rt.OrderNumber == null ? 0 : rt.OrderNumber;
                }
            }
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok();
        }
        #endregion

        #region Change Room Order Number, Floor
        [ApiAuthorize(Roles = "ROLE_HOTEL_OWNER,ROLE_HOTEL_MANAGER")]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("ArrangeRoom")]
        public async Task<IHttpActionResult> ArrangeRoom(List<Rooms> model)
        {
            if(!ModelState.IsValid || model.Count() == 0)
            {
                return BadRequest(ModelState);
            }
            var currentClientUser = Common.UserUtitily.getUserProfile();
            foreach(Rooms room in model)
            {
                var oldRoom = context.Rooms.Where(r => r.HotelId == currentClientUser.HotelId && r.RoomId == room.RoomId).FirstOrDefault();
                if(oldRoom != null)
                {
                    oldRoom.OrderNumber = room.OrderNumber;
                    oldRoom.FloorId = room.FloorId;
                }
            }
            context.SubmitChanges();
            MemoryCacher.ClearStatusCache(currentClientUser.HotelId);
            return Ok();
        }

        #endregion
    }
}

